home *** CD-ROM | disk | FTP | other *** search
- _YOUR OWN HANDPRINTING RECOGNITION ENGINE_
- by Ron Avitzur
-
-
- [LISTING ONE]
-
- /*****************************************************************
- A Writer-Dependent Hand-printing Recognizer -- by Ron Avitzur, 1991.
- This is not the complete code. See the accompanying article for
- a description of other necessary modules.
- *****************************************************************/
-
- typedef struct { short num_items; void *items[]; } *List;
- typedef struct { short code; List strokes; } GesturePattern
- typedef struct { char is_dot; List s[5]; } StrokePattern;
- typedef struct {
- Point Ink[MAX_POINTS],
- P[MAX_N];
- short Ink_Num,
- N,
- T[MAX_N],
- IsDot;
- unsigned long S[5];
- double Aspect_Ratio;
- long Xmax,Xmin,
- Ymax,Ymin,
- Height,Width,
- XmaxT,XminT,
- YmaxT,YminT,
- HeightT,WidthT;
- long start_time,end_time;
- List matches;
- } StrokeData,
- *StrokePtr;
-
- ProcPtr HashFunctions[] = { Fxn1,Fxn2,Fxn3,Fxn4,Fxn5 };
-
- char Bits[] = {2,2,3,2,2};
-
- #define DOT_THRESHHOLD (Wacom?80:4)
- #define PT_SEP_POST (Wacom?40:4)
-
- /****************************************************************/
- void Analyze(register StrokePtr theStroke) {
- char i,s[100];
- Simplify();
- for (i = 0; i < 5; i++) {
- HashFunction[i](s,theStroke);
-
- ConvertStringToLong(s,&S[i],Bits[i]);
- }
- theStroke->IsDot =
- ((theStroke->Height < DOT_THRESHHOLD
- &&
- theStroke->Width < DOT_THRESHHOLD)
- || N == 1);
- }
- /****************************************************************/
- void Simplify(StrokePtr theStroke,Point *Ink,short N) {
- Point Q[MAX_POINTS];
- short min_dx = theStroke->Width / 8,
- min_dy = theStroke->Height / 8;
- if (theStroke->Aspect_Ratio < 0.2) min_dy = theStroke->Height;
- if (theStroke->Aspect_Ratio > 5.0) min_dx = theStroke->Width;
- theStroke->N = Process3(theStroke->P,Ink,N,min_dx,min_dy);
- ComputeT(theStroke);
- }
- /****************************************************************/
- void ComputeT(StrokePtr theStroke) {
- register short *T = theStroke->T;
- register Point *P = theStroke->P;
- register short i,N = theStroke->N;
- for (i = 0; i < N - 1; i++)
- T[i] = ATAN2(P[i+1].v-P[i].v,P[i+1].h-P[i].h);
- }
- /****************************************************************/
- short Process3(register Point *P, register Point *Q,
- short num,short xd, short yd) {
- register short i,n;
- register short dx,dy;
- n = 0;
- P[0] = Q[0];
- for (i = 1; i < num - 1; i++) {
- dx = Q[i].h - P[n].h; dx = ABS(dx);
- dy = Q[i].v - P[n].v; dy = ABS(dy);
- if (dx + dy < PT_SEP_POST) continue;
- if (dx < xd && dy < yd) continue;
- n++;
- P[n] = Q[i];
- }
- dx = Q[num - 1].h - P[n].h;
- dy = Q[num - 1].v - P[n].v;
- if (ABS(dx) + ABS(dy) > PT_SEP_POST)
- n++;
- P[n] = Q[num - 1];
- return n + 1;
- }
- /****************************************************************/
- /* These five lines determine what the features actually are. */
- #define Feature1(t) ('0' + ((t + 10 + 45 + 180) / 90) % 4)
- #define Feature2(t) ('0' + ((t + 10 + 00 + 180) / 90) % 4)
-
- #define Feature3(t) ('0' + ((t + 10 + 22 + 180) / 45) % 8)
- #define Feature4(p) ('0' + (4*((p).h - theStroke->XminT) /theStroke->WidthT))
- #define Feature5(p) ('0' + (4*((p).v - theStroke->YminT) /theStroke->HeightT))
-
- /****************************************************************/
- #define FOO(name,fxn,type,array,end) \
- void name(char *s,StrokePtr theStroke) \
- { \
- register short i,d,n = 0; \
- register type *T = theStroke->array; \
- s[0] = fxn(*T++); \
- i = theStroke->N - end; \
- while (i-- > 0) { \
- d = fxn(*T++); \
- if (s[n] != d) \
- s[++n] = d; \
- } \
- s[++n] = 0; \
- }
- FOO(Fxn1,Feature1,short,T,2)
- FOO(Fxn2,Feature2,short,T,2)
- FOO(Fxn3,Feature3,short,T,2)
- FOO(Fxn4,Feature4,Point,P,1)
- FOO(Fxn5,Feature5,Point,P,1)
- /****************************************************************/
- void ConvertStringToLong(char *s,unsigned long *np,short bits) {
- unsigned long n = 0;
- short i,len = strlen(s);
- s[len] = s[len-1];
- if (len > 32/bits) len = 32/bits;
- for (i = 0; i <= len; i++)
- n = (n << bits) + s[len - i] - '0';
- *np = n;
- }
-